package org.zhangsh.nio;

import org.zhangsh.socket.HostInfo;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * </p>
 *
 * @author zhangsh
 * @version 1.0.0
 * @since 2019-04-18
 */
public class NioEchoSever {

    private static class EchoClinetHandler implements Runnable{

        // 客户端channel，
        private SocketChannel clientChannel = null;
        private boolean flag = true;

        public EchoClinetHandler(SocketChannel clientChannel){
            this.clientChannel = clientChannel;
        }

        @Override
        public void run() {
            ByteBuffer byteBuffer = ByteBuffer.allocate(50);
            try{
                while(flag){
                    byteBuffer.clear();

                    // 将客户端的输入写入缓存
                    int readCount = this.clientChannel.read(byteBuffer);
                    // 客户端的输入字符串
                    String readString = new String(byteBuffer.array(), 0, readCount).trim();
                    System.out.println("[server]接收客户端的信息：" + readString);

                    String writeString = "[ECHO]" + readString + "\n";

                    if("bye".equalsIgnoreCase(readString)){
                        writeString = "byebye";
                        flag = false;
                    }
                    // 以下是输出到客户端的内容
                    byteBuffer.clear();
                    // 将发送的内容写入缓存
                    byteBuffer.put(writeString.getBytes());
                    // 重置
                    byteBuffer.flip();

                    this.clientChannel.write(byteBuffer);
//                    byteBuffer.clear();
                }
                this.clientChannel.close();
            }catch (Exception e){}

        }
    }

    public static void main(String[] args) throws IOException {

        ExecutorService service = Executors.newFixedThreadPool(2);

        // 创建服务端channel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(HostInfo.HOST_PORT));

        // channel管理器
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        //
        System.out.println("服务端监听端口:"+ HostInfo.HOST_PORT);

        int select = 0;
        while((select = selector.select()) > 0){

            Set<SelectionKey> keys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = keys.iterator();

            while(iterator.hasNext()){
                SelectionKey selectionKey = iterator.next();
                if(selectionKey.isAcceptable()){
                    // 实现TCP三次握手
                    SocketChannel clientChannel = serverSocketChannel.accept();
                    if(clientChannel != null){
                        service.submit(new EchoClinetHandler(clientChannel));
                    }
                }else if(selectionKey.isReadable()){

                    // TODO 读事件处理

                }else if(selectionKey.isWritable()){

                    // TODO 写事件

                }
                iterator.remove();
            }
        }
        service.shutdown();
        serverSocketChannel.close();
    }
}
